package com.briup.common.config;

import com.briup.common.properties.RestTemplateConfigProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.*;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * RestTemplate模板配置类
 * @author wood
 */
@ConditionalOnProperty(prefix = "briup.config.rest-template",name = "enabled",havingValue = "true")
@Configuration
public class RestTemplateAutoConfig {

    @Autowired
    private RestTemplateConfigProperties restTemplateConfigProperties;

    @Bean
    public RestTemplate restTemplate(){

        RestTemplate restTemplate = new RestTemplate();
        if(restTemplateConfigProperties.isLog()){
            ClientHttpRequestInterceptor logInterceptor = new LoggingRequestInterceptor();
            List<ClientHttpRequestInterceptor> list = new ArrayList<>();
            list.add(logInterceptor);
            restTemplate.setInterceptors(list);
            restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory()));
        }

        return restTemplate;
    }


    @Slf4j
    private static class LoggingRequestInterceptor implements ClientHttpRequestInterceptor{
        @Override
        public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
            ClientHttpResponse response = execution.execute(request, body);

            log(request,body,response);

            return response;
        }

        private void log(HttpRequest request, byte[] body, ClientHttpResponse response)throws IOException {
            // 如果是向远程认证中心发送认证token的请求，那么就忽略本次远程http调用
            if(request.getURI().toString().contains("/check/token")){
                // NOOP
                return;
            }

            if(log.isDebugEnabled()){

                //response.getStatusCode() == HttpStatus.OK
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                byte[] bys = new byte[512];
                int length;
                InputStream in = response.getBody();
                while ((length = in.read(bys)) != -1) {
                    outputStream.write(bys, 0, length);
                }


                StringBuilder sb = new StringBuilder();
                sb.append("远程http接口调用的情况：")
                        .append("\r\n")
                        .append("------------------------rest request----------------------------")
                        .append("\r\n")
                        .append("request url: ").append(request.getURI())
                        .append("\r\n")
                        .append("request method: ").append(request.getMethodValue())
                        .append("\r\n")
                        .append("request headers: ").append(request.getHeaders())
                        .append("\r\n")
                        .append("request body: ").append(new String(body))
                        .append("\r\n")
                        .append("------------------------------------------------------------------------")
                        .append("\r\n")
                        .append("\r\n")
                        .append("--------------------------------rest response---------------------------")
                        .append("\r\n")
                        .append("response code: ").append(response.getStatusCode())
                        .append("\r\n")
                        .append("response code msg: ").append(response.getStatusText())
                        .append("\r\n")
                        .append("response headers: ").append(response.getHeaders().toString())
                        .append("\r\n")
                        .append("response body: ").append(new String(outputStream.toByteArray(), StandardCharsets.UTF_8))
                        .append("\r\n")
                        .append("---------------------------------------------------------------");

                log.debug(sb.toString());

            }
        }
    }

}
